home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PCMania 81
/
PCMania CD81_1.iso
/
PCMANIA
/
demosc81
/
AFFINE.C
next >
Wrap
C/C++ Source or Header
|
1999-04-22
|
9KB
|
331 lines
/////////////////////////////////////////////////////////////////////////////
// //
// This structs are used for the matrix maths related with the affine //
// transformations of objects & camera. In 3d_math you will find the //
// functions related to inversion & combination of affine transformations //
// //
/////////////////////////////////////////////////////////////////////////////
#include <math.h>
float pi=3.141592654;
typedef struct matrix
{
float m11,m21,m31,m12,m22,m32,m13,m23,m33;
}MATRIX;
typedef struct vector
{
float v1,v2,v3;
}VECTOR;
typedef struct vector2d
{
float v1,v2;
}VECTOR2D;
typedef struct affin
{
MATRIX aff_mtx;
VECTOR aff_vtr;
}AFFIN;
typedef struct implicit_plane
{
VECTOR normal;
float d;
}IMPLICIT_PLANE;
/////////////////////////////////////////////////////////////////////////////
// //
// Various functions used for the matrix maths related with the affine //
// transformations of objects & camera. In 3d_strc you will find the //
// prototypes for the matrix, vector & aff_trns structures. //
// //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// This function gets the Determinant of an 3x3 matrix, as is defined in //
// 3d_strc. It returns a float. //
/////////////////////////////////////////////////////////////////////////////
float det_mtx(MATRIX source)
{
float res;
res=(source.m11*(source.m22*source.m33-source.m23*source.m32)+
source.m12*(source.m23*source.m31-source.m21*source.m33)+
source.m13*(source.m21*source.m32-source.m22*source.m31));
return(res);
}
/////////////////////////////////////////////////////////////////////////////
// This function gets the Inverse of an 3x3 matrix. The result is another //
// 3x3 matrix. This routine may fail if Det(source) is equal to 0, but //
// this is impossible working with standard 3D rotation matrixes //
/////////////////////////////////////////////////////////////////////////////
MATRIX inv_mtx(MATRIX source)
{
MATRIX res;
float det;
det=1/det_mtx(source);
res.m11=det*(source.m22*source.m33-source.m23*source.m32);
res.m12=det*(source.m13*source.m32-source.m12*source.m33);
res.m13=det*(source.m12*source.m23-source.m13*source.m22);
res.m21=det*(source.m23*source.m31-source.m21*source.m33);
res.m22=det*(source.m11*source.m33-source.m13*source.m31);
res.m23=det*(source.m13*source.m21-source.m11*source.m23);
res.m31=det*(source.m21*source.m32-source.m22*source.m31);
res.m32=det*(source.m12*source.m31-source.m11*source.m32);
res.m33=det*(source.m11*source.m22-source.m12*source.m21);
return(res);
}
/////////////////////////////////////////////////////////////////////////////
// This function gets Composition of two 3x3 matrix. The result is another //
// 3x3 matrix. Warning: matrix composition is not commutative!!! //
/////////////////////////////////////////////////////////////////////////////
MATRIX mtx_mul_mtx(MATRIX a, MATRIX b)
{
MATRIX res;
res.m11=a.m11*b.m11+a.m21*b.m12+a.m31*b.m13;
res.m21=a.m11*b.m21+a.m21*b.m22+a.m31*b.m23;
res.m31=a.m11*b.m31+a.m21*b.m32+a.m31*b.m33;
res.m12=a.m12*b.m11+a.m22*b.m12+a.m32*b.m13;
res.m22=a.m12*b.m21+a.m22*b.m22+a.m32*b.m23;
res.m32=a.m12*b.m31+a.m22*b.m32+a.m32*b.m33;
res.m13=a.m13*b.m11+a.m23*b.m12+a.m33*b.m13;
res.m23=a.m13*b.m21+a.m23*b.m22+a.m33*b.m23;
res.m33=a.m13*b.m31+a.m23*b.m32+a.m33*b.m33;
return(res);
}
/////////////////////////////////////////////////////////////////////////////
// This function gets Composition of an 3x3 matrix with a vector. Returns //
// another vector. It's impossible to make the composition between one //
// vector and one matrix. //
/////////////////////////////////////////////////////////////////////////////
VECTOR mtx_mul_vtr(MATRIX a, VECTOR b)
{
VECTOR res;
res.v1=a.m11*b.v1+a.m21*b.v2+a.m31*b.v3;
res.v2=a.m12*b.v1+a.m22*b.v2+a.m32*b.v3;
res.v3=a.m13*b.v1+a.m23*b.v2+a.m33*b.v3;
return(res);
}
/////////////////////////////////////////////////////////////////////////////
// This function simply changes the sign of a vector. //
/////////////////////////////////////////////////////////////////////////////
VECTOR neg_vtr(VECTOR source)
{
VECTOR res;
res.v1=-source.v1;
res.v2=-source.v2;
res.v3=-source.v3;
return(res);
}
/////////////////////////////////////////////////////////////////////////////
// This function just add 2 vectors. //
/////////////////////////////////////////////////////////////////////////////
VECTOR vtr_add_vtr(VECTOR a, VECTOR b)
{
VECTOR res;
res.v1=a.v1+b.v1;
res.v2=a.v2+b.v2;
res.v3=a.v3+b.v3;
return(res);
}
VECTOR vtr_sub_vtr(VECTOR a, VECTOR b)
{
VECTOR res;
res.v1=a.v1-b.v1;
res.v2=a.v2-b.v2;
res.v3=a.v3-b.v3;
return(res);
}
VECTOR mul_vtr(float a, VECTOR b)
{
VECTOR res;
res.v1=a*b.v1;
res.v2=a*b.v2;
res.v3=a*b.v3;
return(res);
}
VECTOR vtr_cross_mul_vtr(VECTOR a, VECTOR b)
{
VECTOR res;
res.v1=a.v2*b.v3-a.v3*b.v2;
res.v2=a.v3*b.v1-a.v1*b.v3;
res.v3=a.v1*b.v2-a.v2*b.v1;
return(res);
}
VECTOR vtr_dir_mul_vtr(VECTOR a, VECTOR b)
{
VECTOR res;
res.v1=a.v1*b.v1;
res.v2=a.v2*b.v2;
res.v3=a.v3*b.v3;
return(res);
}
float vtr_dot_mul_vtr(VECTOR a, VECTOR b)
{
float res;
res=a.v1*b.v1+a.v2*b.v2+a.v3*b.v3;
return(res);
}
float vtr_mix_mul(VECTOR a, VECTOR b, VECTOR c)
{
return(vtr_dot_mul_vtr(a,vtr_cross_mul_vtr(b,c)));
}
float mod_vtr(VECTOR a)
{
return(sqrt(a.v1*a.v1+a.v2*a.v2+a.v3*a.v3));
}
VECTOR unit_vtr(VECTOR a)
{
float res;
res=mod_vtr(a);
if (res!=0)
{
res=1/res;
a.v1*=res;
a.v2*=res;
a.v3*=res;
}
else
{
a.v1=0;
a.v2=0;
a.v3=1;
}
return (a);
}
VECTOR divide_vtr(VECTOR a,float b)
{
float res;
if (b!=0)
{
res=1/b;
a.v1*=res;
a.v2*=res;
a.v3*=res;
}
else
{
a.v1=0;
a.v2=0;
a.v3=1;
}
return (a);
}
/////////////////////////////////////////////////////////////////////////////
// This function gets the Inverse of an affine transformation. The result //
// It returns another affine transformation. //
/////////////////////////////////////////////////////////////////////////////
AFFIN inv_aff(AFFIN source)
{
AFFIN res;
res.aff_mtx=inv_mtx(source.aff_mtx);
res.aff_vtr=mtx_mul_vtr(res.aff_mtx,neg_vtr(source.aff_vtr));
return(res);
}
MATRIX i_mtx(MATRIX source)
{
MATRIX res;
res.m11=source.m22*source.m33-source.m23*source.m32;
res.m12=source.m13*source.m32-source.m12*source.m33;
res.m13=source.m12*source.m23-source.m13*source.m22;
res.m21=source.m23*source.m31-source.m21*source.m33;
res.m22=source.m11*source.m33-source.m13*source.m31;
res.m23=source.m13*source.m21-source.m11*source.m23;
res.m31=source.m21*source.m32-source.m22*source.m31;
res.m32=source.m12*source.m31-source.m11*source.m32;
res.m33=source.m11*source.m22-source.m12*source.m21;
return(res);
}
AFFIN i_aff(AFFIN source)
{
AFFIN res;
res.aff_mtx=i_mtx(source.aff_mtx);
res.aff_vtr=mtx_mul_vtr(res.aff_mtx,neg_vtr(source.aff_vtr));
return(res);
}
/////////////////////////////////////////////////////////////////////////////
// This is the affine transformation compositon function. It's RES=(A(B)) //
/////////////////////////////////////////////////////////////////////////////
AFFIN aff_mul_aff(AFFIN a, AFFIN b)
{
AFFIN res;
res.aff_mtx=mtx_mul_mtx(a.aff_mtx,b.aff_mtx);
res.aff_vtr=vtr_add_vtr(mtx_mul_vtr(a.aff_mtx,b.aff_vtr),a.aff_vtr);
return(res);
}
AFFIN AxA(AFFIN a, AFFIN b)
{
AFFIN res;
res.aff_mtx=mtx_mul_mtx(a.aff_mtx,b.aff_mtx);
res.aff_vtr=vtr_add_vtr(mtx_mul_vtr(a.aff_mtx,b.aff_vtr),a.aff_vtr);
return(res);
}
VECTOR AxV(AFFIN a, VECTOR b)
{
VECTOR res;
res=vtr_add_vtr(mtx_mul_vtr(a.aff_mtx,b),a.aff_vtr);
return(res);
}
IMPLICIT_PLANE calc_plane(VECTOR a, VECTOR b, VECTOR c)
{
IMPLICIT_PLANE res;
res.normal=unit_vtr(vtr_cross_mul_vtr(vtr_sub_vtr(b,a),vtr_sub_vtr(c,a)));
res.d=-vtr_dot_mul_vtr(res.normal,c);
return(res);
}
VECTOR calc_normal(VECTOR a, VECTOR b, VECTOR c)
{
VECTOR res;
res=unit_vtr(vtr_cross_mul_vtr(vtr_sub_vtr(b,a),vtr_sub_vtr(c,a)));
return(res);
}
float dist_to_plane(IMPLICIT_PLANE p, VECTOR v)
{
return (vtr_dot_mul_vtr(p.normal,v)+p.d);
}